<?php
/**
 * SLS_BoRights Tool - Check authentification and authorizations in customer back-office
 *  
 * @author Laurent Bientz 
 * @copyright SillySmart
 * @package SLS.Generics.Tools.SLS_Bo
 * @since 1.0 
 */
class SLS_BoRights
{
	/**
	 * Check if an admin is authorized to log in
	 *
	 * @access public static
	 * @param string $login login
	 * @param string $pwd password
	 * @return bool true if connected, else false
	 * @since 1.0
	 */
	public static function connect($login,$pwd)
	{
		$generic = SLS_Generic::getInstance();
		$session = $generic->getObjectSession();
		$sessionToken = substr(substr(sha1($generic->getSiteConfig("privateKey")),12,31).substr(sha1($generic->getSiteConfig("privateKey")),4,11),6);
		
		$pathsHandle = file_get_contents($generic->getPathConfig("configSls")."/rights.xml");
		$xmlRights = new SLS_XMLToolbox($pathsHandle);		
		$result = array_shift($xmlRights->getTagsAttributes("//sls_configs/entry[@login='".($login)."' and @password='".sha1($pwd)."']",array("login")));
		
		if (!empty($result))
		{
			$session->setParam("SLS_BO_VALID_".$sessionToken,"true");	
			$session->setParam("SLS_BO_USER_".$sessionToken,$login);
			$session->setParam("SLS_BO_USER",$login);
			$session->setParam("ckfinderAuthorized",true);
			return true;
		}
		else
			return false;
	}
	
	/**
	 * Disconnect an admin
	 * 
	 * @access public static
	 * @since 1.0
	 */
	public static function disconnect()
	{		
		$generic = SLS_Generic::getInstance();
		$session = $generic->getObjectSession();
		$sessionToken = substr(substr(sha1($generic->getSiteConfig("privateKey")),12,31).substr(sha1($generic->getSiteConfig("privateKey")),4,11),6);
		
        $session->delParam("SLS_BO_VALID_".$sessionToken);
        $session->delParam("SLS_BO_USER_".$sessionToken);
        $session->delParam("SLS_BO_USER");
        $session->delParam("ckfinderAuthorized");
	}
	
	/**
	 * Check if an admin is logged
	 *
	 * @access public static
	 * @return bool true if logged, else false
	 * @since 1.0
	 */
	public static function isLogged()
	{
		$generic = SLS_Generic::getInstance();
		$session = $generic->getObjectSession();		
		$sessionToken = substr(substr(sha1($generic->getSiteConfig("privateKey")),12,31).substr(sha1($generic->getSiteConfig("privateKey")),4,11),6);
		
		if ($session->getParam("SLS_SESSION_VALID_".$sessionToken) == "true")
		{
			$session->setParam("SLS_BO_VALID_".$sessionToken,"true");
			$session->setParam("SLS_BO_USER_".$sessionToken,$session->getParam('SLS_SESSION_USER_'.$sessionToken));
			$session->setParam("SLS_BO_USER",$session->getParam('SLS_SESSION_USER_'.$sessionToken));
			$session->setParam("ckfinderAuthorized",true);
		}		
		if ($session->getParam("SLS_BO_VALID_".$sessionToken) == "true")
			return true;
		else
			return false;
	}
	
	/**
	 * Check if the current admin is authorized to access on this back-office action
	 *
	 * @access public static
	 * @param string $type the role of action ('read'|'add'|'edit'|'delete'|'clone'|'email')
	 * @param string $entity the entity on which you want to test privilege
	 * @param string $aid the action id you want to test privilege
	 * @return int $authorized -1 if not logged, 0 is not authorized, 1 if ok
	 * @since 1.0
	 */
	public static function isAuthorized($role="read",$entity="",$aid="")
	{		
		$generic = SLS_Generic::getInstance();
		$session = $generic->getObjectSession();
		$xmlController = $generic->getControllersXML();
		
		$result = array_shift($xmlController->getTagsAttribute("//controllers/controller[@isBo='true']","name"));
		$controllerBo = $result["attribute"];
		switch($role)
		{
			case "read": $scontrollerBo = "List".$entity; break;
			case "edit": $scontrollerBo = "Modify".$entity; break;
			default: $scontrollerBo = ucfirst($role).$entity; break;
		}
		$actionExist = array_shift($xmlController->getTags("//controllers/controller[@name='".$controllerBo."']/scontrollers/scontroller[@name='".$scontrollerBo."']/@id"));		
		$sessionToken = substr(substr(sha1($generic->getSiteConfig("privateKey")),12,31).substr(sha1($generic->getSiteConfig("privateKey")),4,11),6);
		$xmlRights = new SLS_XMLToolbox(file_get_contents($generic->getPathConfig("configSls")."/rights.xml"));
		$authorized = 0;
				
		if (self::isLogged())
		{	
			if ($session->getParam("SLS_SESSION_VALID_".$sessionToken) == "true")
				return 1;
			
			if ($generic->actionIdExists($aid))
			{				
				$result = array_shift($xmlRights->getTags("//sls_configs/entry[@login='".($session->getParam("SLS_BO_USER"))."']/action[@id='".$aid."']/@id"));
				$authorized = (!empty($result)) ? 1 : 0;
			}
			else
			{
				$result = array_shift($xmlRights->getTags("//sls_configs/entry[@login='".($session->getParam("SLS_BO_USER"))."']/action[@role='".$role."' and @entity='".$entity."']/@id"));
				$authorized = (!empty($result) || empty($actionExist)) ? 1 : 0;
			}
			
			return $authorized;
		}
		else
			return -1;
	}
		
	/**
	 * Returns all the bo listing actions
	 * 
	 * @access public static
	 * @return array $actions all the actions with key label and key url
	 * @since 1.0
	 */
	public static function getDistinctActions($format="")
	{
		$generic = SLS_Generic::getInstance();
		$xmlController = $generic->getControllersXML();
				
		$result = array_shift($xmlController->getTagsAttribute("//controllers/controller[@isBo='true']","name"));
		$controller = $result["attribute"];
				
		$result = $xmlController->getTagsAttribute("//controllers/controller[@isBo='true']/scontrollers/scontroller","name");
		$actions = array();
		$actionB = array("label" 	=> "Connection",
					     "url" 		=> $generic->getProtocol()."://".$generic->getSiteConfig("domainName")."/".$controller."/Connection.sls",
						 "selected"	=> ($generic->getActionId() == $generic->getActionId($controller,"Translation")) ? "true" : "false");
		
		$tables = SLS_Sql::getInstance()->select("SHOW TABLE STATUS FROM `".$generic->getDbConfig("base",SLS_Sql::getInstance()->getCurrentDb())."`");
		$comments = array();
		for($i=0 ; $i<$count=count($tables) ; $i++)
			$comments[SLS_String::tableToClass($tables[$i]->Name)] = (SLS_String::contains($tables[$i]->Comment,"InnoDB free")) ? SLS_String::substrBeforeFirstDelimiter($tables[$i]->Comment,"; InnoDB free") : $tables[$i]->Comment;
				
		for($i=0 ; $i<$count=count($result) ; $i++)
		{
			$attribute = $result[$i]["attribute"];			
			if (SLS_String::startsWith($attribute,"List"))
			{				
				$arrayTmp = array();
				$className = SLS_String::substrAfterFirstDelimiter($attribute,"List");
				$db = SLS_String::substrBeforeFirstDelimiter($className,"_");
				$name = SLS_String::substrAfterFirstDelimiter($className,"_");				
				$generic->useModel($name,$db,'user');
				$object = new $className();
				
				$label = $comments[$name];
				if (empty($label))
					$label = $name;
				
				$arrayTmp["label"] 		= $label;
				$arrayTmp["url"]		= $generic->getFullPath($controller,$attribute);
				$arrayTmp["selected"] 	= ($generic->getActionId() == $generic->getActionId($controller,"List".$className) ||
										   $generic->getActionId() == $generic->getActionId($controller,"Add".$className) ||
										   $generic->getActionId() == $generic->getActionId($controller,"Modify".$className) ||
										   $generic->getActionId() == $generic->getActionId($controller,"Email".$className)) ? "true" : "false";
				if (self::isAuthorized("read",$className))
					array_push($actions,$arrayTmp);
			}
		}
		
		$translation = array_shift($xmlController->getTags("//controllers/controller[@isBo='true']/scontrollers/scontroller[@name='Translation']/@id"));
		$upload = array_shift($xmlController->getTags("//controllers/controller[@isBo='true']/scontrollers/scontroller[@name='FileUpload']/@id"));
		
		if (!empty($translation) && self::isAuthorized("custom","",$translation))
		{
			$arrayTmp["label"] 		= "0. Translations";
			$arrayTmp["url"]		= $generic->getProtocol()."://".$generic->getSiteConfig("domainName")."/".$controller."/Translation.sls";
			$arrayTmp["selected"] 	= ($generic->getActionId() == $generic->getActionId($controller,"Translation")) ? "true" : "false";
			array_push($actions,$arrayTmp);
		}
		if (!empty($upload)  && self::isAuthorized("custom","",$upload))
		{
			$arrayTmp["label"] 	= "FileUpload";
			$arrayTmp["url"]	= $generic->getProtocol()."://".$generic->getSiteConfig("domainName")."/".$controller."/FileUpload.sls";
			$arrayTmp["selected"] 	= ($generic->getActionId() == $generic->getActionId($controller,"FileUpload")) ? "true" : "false";
			array_push($actions,$arrayTmp);
		}
		
		usort($actions,"SLS_BoRights::boActionsSort");
		array_push($actions,$actionB);
		
		$arrayTmp["label"] 	= "Disconnection";
		$arrayTmp["url"]	= $generic->getProtocol()."://".$generic->getSiteConfig("domainName")."/".$controller."/Disconnection.sls";
		array_push($actions,$arrayTmp);
		
		if ($format == "xml")
		{
			$xml = new SLS_XMLToolbox(false);
			$xml->startTag("ul");
			foreach($actions as $action)
			{
				if (in_array($action["label"], array("Connection", "Disconnection")))
					continue;
					
				$xml->startTag("li");
					$xml->addFullTag("a", $action["label"], false, array("href" => $action["url"]));
				$xml->endTag("li");
			}
			$xml->endTag("ul");
			
			return $xml->getXML();
		}
		else
			return $actions;
	}
	
	/**
	 * Callback function to order array of bo actions
	 *
	 * @param array $a
	 * @param array $b
	 * @return int
	 */
	public static function boActionsSort($a,$b)
	{
		return (strcasecmp($a["label"],$b["label"])>0) ? 1 : 0;
	}
	
	/**
	 * If action bo exist
	 *	 
	 * @param string $alias the alias of the db
	 * @param string $model the model to check
	 * @param string $action the action to test
	 * @return bool true if exist, else false
	 */
	public static function boActionExist($alias,$model,$action)
	{
		$controllersXML = SLS_Generic::getInstance()->getControllersXML();		
		$test = array_shift($controllersXML->getTags("//controllers/controller[@isBo='true']/scontrollers/scontroller[@name='".ucfirst($action).ucfirst($alias)."_".SLS_String::tableToClass($model)."']"));
		return (empty($test)) ? false : true;
	}
}
?>